package org.wannatrak.android.activity;

import android.app.Dialog;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.provider.Settings;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.*;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;
import org.json.JSONArray;
import org.json.JSONObject;
import org.wannatrak.android.ApplicationContext;
import org.wannatrak.android.R;
import org.wannatrak.android.exceptions.HttpException;
import org.wannatrak.android.helper.DateHelper;
import org.wannatrak.android.helper.DialogHelper;
import org.wannatrak.android.helper.UIHelper;
import org.wannatrak.android.intf.DialogAction;
import org.wannatrak.android.intf.ItemClickAction;
import org.wannatrak.android.maps.PointsOverlay;

import java.util.*;

/**
 * @Author: Maksim Tulupov maxtulupov@gmail.com
 * @Date: $Date: 2011-07-07 05:24:32 +0000 (Thu, 07 Jul 2011) $ 5:24 PM
 * @version: $Revision: 25 $
 * @id: $Id: ViewTrackActivity.java 25 2011-07-07 05:24:32Z maxtulupov@gmail.com $
 */
public class ViewTrackActivity extends MapActivity {

    /**
     * thread for executing async login
     */
    private Thread t;

    /**
     * dialog that shows async execution
     */
    private Dialog dialog;

    private static int selectedPosition = -1;

    private Map<String, String> tracks = new HashMap<String, String>();

    private Date previousStartDate;

    private Date previousEndDate;

    private Date startDate;

    private Date endDate;

    private String currentTrackName;

    @Override
    protected boolean isRouteDisplayed() {
        return false;
    }

    @Override
    protected void onCreate(Bundle bundle) {
        super.onCreate(bundle);
        setContentView(R.layout.map_view);
        getIntentParams();
        init();
    }

    @Override
    public Object onRetainNonConfigurationInstance() {
        if (dialog != null && dialog.isShowing()) {
            dialog.dismiss();
        }
        return super.onRetainNonConfigurationInstance();
    }

    private void getIntentParams() {
        Bundle bundle = getIntent().getExtras();
        if (bundle != null) {
            if (bundle.containsKey("currentTrack")) {
                currentTrackName = bundle.getString("currentTrack");
            }
        }
    }

    private void init() {
        startDate = createDefaultStartDate();
        endDate = createDefaultEndDate();
        ((TextView) findViewById(R.id.from)).setText(ApplicationContext.getFormatter(Date.class).format(startDate));
        ((TextView) findViewById(R.id.to)).setText(ApplicationContext.getFormatter(Date.class).format(endDate));
        final Spinner spinner = (Spinner) findViewById(R.id.tracksSpinner);
        dialog = DialogHelper.createProgressDialog(ViewTrackActivity.this);
        final MapViewSpinnerHandler handler = new MapViewSpinnerHandler(ViewTrackActivity.this);
        dialog.show();
        Runnable r = new Runnable() {
            public void run() {
                Looper.prepare();
                try {
                    SpinnerAdapter spinnerAdapter = loadTracks();
                    if (spinnerAdapter != null) {
                        Message message = handler.obtainMessage(1234, spinnerAdapter);
                        message.arg1 = selectedPosition;
                        handler.sendMessage(message);
                    }
                } catch (Exception e) {
                    handler.sendMessage(handler.obtainMessage(-1234, e.getMessage()));
                } finally {
                    dialog.dismiss();
                }
            }
        };
        t = new Thread(r);
        t.start();

        UIHelper.setActionToView(spinner, new ItemClickAction() {
            public boolean onItemSelect(AdapterView parent, final View view, int position, long id) {
                selectedPosition = position;
                dialog = DialogHelper.createProgressDialog(ViewTrackActivity.this);
                final MapViewDialogHandler handler = new MapViewDialogHandler(ViewTrackActivity.this);
                dialog.show();
                Runnable r = new Runnable() {
                    public void run() {
                        Looper.prepare();
                        try {
                            String name = ((TextView) view.findViewById(android.R.id.text1)).getText().toString();
                            initOverlays(name, handler);
                        } finally {
                            dialog.dismiss();
                        }
                    }
                };
                t = new Thread(r);
                t.start();
                return true;
            }

            public void onNothingSelected(AdapterView parent) {
            }
        });
        initMap();

        DialogHelper.setDateDialogToTextView(this, (TextView) findViewById(R.id.from), new DialogHelper.OnDateSetListener() {
            public void onSet(DatePicker datePicker, int year, int month, int day) {
                startDate = DateHelper.getDate(year, month, day);
                if (!startDate.equals(previousStartDate)) {
                    previousStartDate = startDate;
                    TextView textView = (TextView) findViewById(R.id.to);
                    if (textView.getText() == null || "".equals(textView.getText().toString())) {
                        endDate = createDefaultEndDate();
                    }
                    dateChanged();
                }
            }
        });

        DialogHelper.setDateDialogToTextView(this, (TextView) findViewById(R.id.to), new DialogHelper.OnDateSetListener() {
            public void onSet(DatePicker datePicker, int year, int month, int day) {
                endDate = DateHelper.getDate(year, month, day);
                if (!endDate.equals(previousEndDate)) {
                    previousEndDate = endDate;
                    TextView textView = (TextView) findViewById(R.id.from);
                    if (textView.getText() == null || "".equals(textView.getText().toString())) {
                        startDate = createDefaultStartDate();
                    }
                    dateChanged();
                }
            }
        });
    }

    private void dateChanged() {
        final Spinner spinner = (Spinner) findViewById(R.id.tracksSpinner);
        final View view = spinner.getSelectedView();
        if (view != null) {
            final Dialog dialog = DialogHelper.createProgressDialog(ViewTrackActivity.this);
            final MapViewDialogHandler handler = new MapViewDialogHandler(ViewTrackActivity.this);
            dialog.show();
            Runnable r = new Runnable() {
                public void run() {
                    Looper.prepare();
                    try {
                        String name = ((TextView) view.findViewById(android.R.id.text1)).getText().toString();
                        initOverlays(name, handler);
                    } finally {
                        dialog.dismiss();
                    }
                }
            };
            new Thread(r).start();
        }
    }

    private void initOverlays(String name, Handler handler) {
        String trackId = tracks.get(name);
        if (trackId != null) {
            try {
                List<OverlayItem> overlays = ApplicationContext.getWannatrakService().loadItems(
                        trackId, name, startDate.getTime(), endDate.getTime());
                handler.sendMessage(handler.obtainMessage(1234, overlays));
            } catch (HttpException e) {
                Log.e(getClass().getSimpleName(), "error loading overlays", e);
                handler.sendMessage(handler.obtainMessage(-1234, e.getMessage()));
            }
        }
    }

    private void initMap() {
        MapView mapView = (MapView) findViewById(R.id.mapView);
        mapView.setBuiltInZoomControls(true);
        mapView.getController().setZoom(15);
    }

    private SpinnerAdapter loadTracks() throws Exception {
        JSONArray array = ApplicationContext.getWannatrakService().loadTracks();
        String[] arr = new String[array.length()];
        for (int i = 0; i < array.length(); i++) {
            String name = ((JSONObject) array.get(i)).getString("name");
            String id = ((JSONObject) array.get(i)).getString("id");
            arr[i] = name;
            tracks.put(name, id);
            if (name.equals(currentTrackName)) {
                selectedPosition = i;
            }
        }
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.dropdown_item, arr);
        adapter.setDropDownViewResource(R.layout.dropdown_item);
        return adapter;
    }

    private Date createDefaultStartDate() {
        return DateHelper.createDateMidnight(new Date());
    }

    private Date createDefaultEndDate() {
        Calendar c = Calendar.getInstance();
        c.setTimeInMillis(System.currentTimeMillis());
        c.add(Calendar.DAY_OF_YEAR, 1);
        return DateHelper.createDateMidnight(c.getTime());
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.context_menu, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.help:
                Intent i = new Intent(Intent.ACTION_VIEW);
                i.setData(Uri.parse(AbstractContextMenuActivity.HELP_URL + Locale.getDefault().getDisplayLanguage()));
                startActivity(i);
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }
}
